package com.lagou.listener;

import ch.qos.logback.classic.spi.EventArgUtil;
import com.lagou.client.ZkClientUtil;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author
 */
@Component
public class ProviderListener {

    @Autowired
    private ZkClientUtil zkClientUtil;

    private volatile long beginTimeMillis;

    private static final String ZERO = "0";

    /**
     * 当前是否正在进行超时检测
     */
    private static volatile AtomicBoolean isStartCheck = new AtomicBoolean(false);

    private static ExecutorService executorService = Executors.newSingleThreadExecutor();

    /**
     * 1. 设置当前在进行检测
     * 2. 超时设置为0，之后不进行检测
     * 3. 新的请求到来之后，重新进行检测
     *
     * @throws Exception
     */
    public void checkSessionIsTimeOut() throws Exception {
        isStartCheck.set(true);
        CuratorFramework zkClient = zkClientUtil.getZkClient();
        while (true){
            //超过5s没有收到请求，响应时间设置为0
            if(System.currentTimeMillis() - getBeginTimeMillis() > 5000){
                System.out.println("===> 超过5s没有收到新的请求，将节点的响应时间设置为0");
                //如果节点不存在则创建，存在更新响应时间
                if(zkClient.checkExists().forPath(zkClientUtil.getPath()) == null){
                    zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(zkClientUtil.getPath(), ZERO.getBytes());
                } else {
                    zkClient.setData().forPath(zkClientUtil.getPath(), ZERO.getBytes());
                }
                break;
            }
        }
        isStartCheck.set(false);
    }

    public long getBeginTimeMillis() {
        return beginTimeMillis;
    }

    public void setBeginTimeMillis(long beginTimeMillis) throws Exception {
        this.beginTimeMillis = beginTimeMillis;
        //如果当前没有在进行检测请求超时，进行检测
        if(!isStartCheck.get()){
            Runnable runnable = () -> {
                try {
                    checkSessionIsTimeOut();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
            executorService.submit(runnable);
        }
    }
}
